import 'dart:async';

import 'package:flutter/cupertino.dart';
import 'package:flutter_demo/pages/page_with_title.dart';
import 'package:flutter_demo/widgets/app_widgets.dart';

class AsyncPage extends PageWithTitle {
  const AsyncPage() : super("异步组件(StreamBuilder,FutureBuilder)");

  @override
  List<Widget> buildContentWidgets(BuildContext context) {
    return const [
      PrimaryTitle("简介"),
      BodyText("Flutter采用的是Dart语言，本身Dart语言就有异步的API，而Flutter为此也封装了"
          "一套根据异步任务状态更新的组件，免去开发者管理订阅的生命周期处理。"),
      AppSpacer.large,
      _StreamExample(),
      UlItem("StreamBuilder"),
      BodyText("流式构建器，订阅一个流，跟随数据快照的变化重建组件"),
      LabelText("- initialData，初始数据快照"),
      LabelText("- stream，数据流，通常我们可以通过StreamController来构建一个流"),
      LabelText("- builder，根据数据当前状态和数据构建组件"),
      AppSpacer.large,
      _FutureExample(),
      UlItem("FutureBuilder"),
      BodyText("异步任务构建器，根据异步任务执行结果重建组件，它的使用与StreamBuilder类似，"
          "只是少了中间数据更新的回调，他一步到位返回最终结果"),
      AppSpacer.large,
      NoticeText("注意，数据快照的重要参数"),
      NoticeText("- connectionState，异步任务状态"),
      NoticeText("  - none，初始状态"),
      NoticeText("  - waiting，等待，即任务已经开始但还没返回任何数据"),
      NoticeText("  - active，激活，即任务已经开始陆续返回数据，对于Future不会有这一步"),
      NoticeText("  - done，任务已完成"),
      NoticeText("- hasError，在任务完成时，用于判断任务是否因为错误而结束，通过error可以拿到错误对象进行分析"),
      NoticeText("- hasData，在任务完成时，用于判断任务是否有携带数据，对于Stream也可以用于在active阶段获取数据更新"),
    ];
  }
}

class _StreamExample extends StatefulWidget {
  const _StreamExample();

  @override
  State<StatefulWidget> createState() {
    return _StreamExampleState();
  }
}

class _StreamExampleState extends State<_StreamExample> {
  final _streamController = StreamController<String>();

  @override
  void initState() {
    super.initState();
    _runTask();
  }

  void _runTask() async {
    var runTimes = 0;
    await Future.doWhile(() async {
      await Future.delayed(const Duration(seconds: 1));
      runTimes++;
      _streamController.sink.add("$runTimes");
      return runTimes < 4;
    });
    _streamController.close();
  }

  @override
  void dispose() {
    _streamController.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
        stream: _streamController.stream,
        builder: (context, snapshot) {
          if(snapshot.connectionState == ConnectionState.active){
            return Text("data updating...${snapshot.requireData}");
          }else if(snapshot.connectionState == ConnectionState.done){
            return Text("finished...${snapshot.requireData}");
          }else{
            return const Text("loading...");
          }
        });
  }
}

class _FutureExample extends StatefulWidget {
  const _FutureExample();

  @override
  State<StatefulWidget> createState() {
    return _FutureExampleState();
  }
}

class _FutureExampleState extends State<_FutureExample> {
  Future<int> _runTask() async {
    var runTimes = 0;
    return Future.doWhile(() async {
      runTimes++;
      await Future.delayed(const Duration(seconds: 1));
      return runTimes < 4;
    }).then((v) {
      return runTimes;
    });
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _runTask(),
      builder: (context, snapshot) {
        if(snapshot.connectionState == ConnectionState.done){
          return Text("finished...${snapshot.requireData}");
        }else{
          return const Text("loading...");
        }
      },
    );
  }
}
